<?php
/**
 * 内部使用模块 * 不允许web调用
 * 
 * @return void
 */
function g_init()
{
	redirect(url(ROUTE_HTML_APP, url_params(ROUTE_DEFAULT_APP,ROUTE_DEFAULT_Q) ));
}

/* 仓鼠 */

define('G_TIMESTAMP', time());
define('G_ROOT', dirname(__FILE__));

class G
{

	/**
	 * @var SqlDataSource
	 */
	static $ds = null;

	static function computed_style_replace($str,$split_char='-'){
		return preg_replace("/(?=[A-Z])/",$split_char,$str);
	}

	static function computed_style_merge($str,$first_upper=false,$split_char='-'){
		$sections = G::normalize($str,$split_char);
		$str = '';
		if (!empty($sections)){
			$firstWord = array_shift($sections);
			if ($first_upper) $firstWord = ucfirst($firstWord);
			
			if (!empty($sections)){
				foreach ($sections as $sec){
					$str .= ucfirst($sec);
				}
			}
			$str = "{$firstWord}{$str}";
		}
		return $str;
	}

	static function normalize($input, $delimiter = ',')
	{
		if (!is_array($input))
		{
			$input = explode($delimiter, $input);
		}
		$input = array_map('trim', $input);
		return array_filter($input, 'strlen');
	}
	
	static function fast_uuid($suffix_len=3)
	{
		//! 计算种子数的开始时间
        static $being_timestamp = 1421833799;
        
        $time = explode(' ', microtime());
        $id = ($time[1] - $being_timestamp) . sprintf('%06u', substr($time[0], 2, 6));
        if ($suffix_len > 0)
        {
            $id .= substr(sprintf('%010u', mt_rand()), 0, $suffix_len);
        }
        return $id;
	}

	static function identify($x)
	{
		static $mask = '0123456789abcdefghijklmnopqrstuvwxyz';
		$x = sprintf("%u", crc32($x));

		$m = '';
		while ($x > 0)
		{
			$s = $x % 36;
			$m .= $mask[$s];
			$x = floor($x / 36);
		}
		return $m;
	}

	static function val($arr, $name, $default = null)
	{
	    return isset($arr[$name]) ? $arr[$name] : $default;
	}

	static function error($errcode, $errmsg='')
	{
		$data = array(
				'errcode' => $errcode,
				'errmsg'   => $errmsg
			);
		echo json_encode($data, JSON_NUMERIC_CHECK);// | JSON_FORCE_OBJECT
		exit;
	}

	static function success($data=array())
	{
		echo json_encode($data, JSON_NUMERIC_CHECK);
		exit;
	}

	/**
	 * 遍历指定目录及子目录下的文件，返回所有与匹配模式符合的文件名
	 *
	 * @param string $dir
	 * @param string $pattern
	 *
	 * @return array
	 */
	static function recursion_glob($dir, $pattern)
	{
		if ( !is_dir($dir) ) return array();
		
	    $dir = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR;
	    $files = array();

	    $dh = opendir($dir);
	    if (!$dh) return $files;

	    $items = (array)glob($dir . $pattern);
	    foreach ($items as $item)
	    {
	        if (is_file($item)) $files[] = $item;
	    }

	    while (($file = readdir($dh)))
	    {
	        if ($file == '.' || $file == '..') continue;

	        $path = $dir . $file;
	        if (is_dir($path))
	        {
	            $files = array_merge($files, G::recursion_glob($path, $pattern));
	        }
	    }
	    closedir($dh);
	    return $files;
	}


	/**
	 * 创建一个目录树
	 *
	 * 用法：
	 * <code>
	 * G::mkdirs('/top/second/3rd');
	 * </code>
	 *
	 * @param string $dir
	 * @param int $mode
	 */
	static function mkdirs($dir, $mode = 0777)
	{
	    if (!is_dir($dir)) {
			// 使用了 php5 新增的 $recursive
	        return mkdir($dir, $mode,true);
	    }
	    return true;
	}
	
	/**
	 * 删除指定目录及其下的所有文件和子目录
	 *
	 * 用法：
	 * <code>
	 * // 删除 my_dir 目录及其下的所有文件和子目录
	 * G::rmdirs('/path/to/my_dir');
	 * </code>
	 *
	 * 注意：使用该函数要非常非常小心，避免意外删除重要文件。
	 *
	 * @param string $dir
	 */
	static function rmdirs($dir)
	{
	    $dir = realpath($dir);
	    if ($dir == '' || $dir == '/' ||
	        (strlen($dir) == 3 && substr($dir, 1) == ':\\'))
	    {
	        // 禁止删除根目录
	        return false;
	    }
	
	    // 遍历目录，删除所有文件和子目录
	    if(false !== ($dh = opendir($dir))) {
	        while(false !== ($file = readdir($dh))) {
	            if($file == '.' || $file == '..') { continue; }
	            $path = $dir . DIRECTORY_SEPARATOR . $file;
	            if (is_dir($path)) {
	                if (!G::rmdirs($path)) { return false; }
	            } else {
	                unlink($path);
	            }
	        }
	        closedir($dh);
	        rmdir($dir);
	        return true;
	    }
	    return false;
	}

}


### sf 反射相关

function g_sf_list($app, $g_sf_meta='g_sf_meta')
{
	$dir = APP_DIR . "/app/{$app}/_sf" . DIRECTORY_SEPARATOR;
	$paths = G::recursion_glob($dir,'*.php');
	if (empty($paths)) return array();
	
	$sfs = array();
	foreach ($paths as $path){
		// 1. 去掉基准路径
		$q = str_replace($dir,'',$path);
		// 2. 去掉后缀
		$q = preg_replace('/\.php$/i','',$q);
		// 3. 拆分过滤 
		$q = G::normalize($q,DIRECTORY_SEPARATOR);
		if (empty($q)) continue;
		$q = implode('.', $q);

		$sffunc = g_sf_get($app, $q);
		if ( $sffunc )
		{
			$sfs[$q] = g_sf_meta($sffunc);
		}
	}
	
	return $sfs;
}

function g_sf_get($app, $q)
{
	$q = strtolower($q);
	$func = "{$app}_sf_" . str_ireplace('.', '_', $q);
	if ( !is_callable($func) )
	{
		$dir = APP_DIR . "/app/{$app}/_sf" . DIRECTORY_SEPARATOR;
		$file = $dir . str_ireplace('.', DIRECTORY_SEPARATOR, $q) . '.php';

		if ( file_exists($file) )
		{
			require_once $file;
			if ( is_callable($func) ) return $func;
		}
	}

	return false;
}

function g_sf_meta($sffunc)
{
	if ( !is_callable($sffunc) ) return false;

	$rf = new ReflectionFunction($sffunc);

	$ins = InspectFunc::parse($rf->getDocComment());
	$doc = array();
	$doc['descr'] = $ins->getDescr();
	$doc['params'] = $ins->getParams();
	$doc['example'] = $ins->getExample();
	$doc['data'] = $ins->getData();
	$doc['author'] = $ins->getTag('@author');
	$doc['edit'] = $ins->getTag('@edit');
	$doc['type'] = $ins->getTag('@type');

	$doc['role'] = $ins->getTag('@role');
	return $doc;
}